Q3 次の10進数表現されたIPアドレスを2進数32桁に変換してください。できた人は逆変換の方法も考えてみてください。
from 第43回 シェル芸勉強会振り返り 問題と解答
Q3 次の10進数表現されたIPアドレスを2進数32桁に変換してください。できた人は逆変換の方法も考えてみてください。
ちょっと悩んだけれど、いけた
bcとbashの数値変換を使う2パターンが思いついたけれど、dcという古いコマンドを使うパターンもあったみたい
僕の解答は下記
$ echo 192.168.10.55 | tr "." " " | while read a b c d; do f() { printf "%08d." $(echo "ibase=10; obase=2; $1" | bc); }; f $a; f $b; f $c; f $d ; done
11000000.10101000.00001010.00110111.
末尾にゴミが残ってしまってるが
whileループの中で関数を定義するとかいう無駄なことしてるけれど、きちんと動く
直すのがめんどくさかった
bcコマンドで10進数と2進数の相互変換
あとはprintfで0埋め8桁に揃えた
最初の解答したあと、以下のようにも解けるなぁってことに気づいた
$ echo 192.168.10.55 | tr "." \\n | sed -E 's@.*@echo "ibase=10; obase=2; &" | bc | xargs printf %08d.@ge' | tr -d \\n | sed -E 's/.$//g'
10進数をそれぞれ1行ずつに分割
sedで前述のbcを呼び出すシェルのコマンド列の文字列に置換して、eでシェルとして実行
1行に戻して
行末の.を消す
こっちはちょっとトリッキーなアプローチだと思う
逆変換は忘れてたけれど、bcのobaseとibaseの数値を入れ替えればいけると思う
Bashの数値変換では、算術演算式の中で専用の記法を使って10進数、2進数変換ができる
$ echo $(( 2#1111 ))
15
$ echo $((10#15))
15
$ echo $((16#f))
15
他にもprintfを使ったアプローチもありそう
シェルで2進数、8進数、10進数、16進数変換@bash | Mazn.net